from rest_framework_jwt.views import ObtainJSONWebToken
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView

from fuguangapi.utils.tencentcloudapi import TencentCloudAPI, TencentCloudSDKException
from .models import User
from rest_framework.generics import CreateAPIView
from .serializers import UserRegisterModelSerializer



# Create your views here.
class LoginAPIView(ObtainJSONWebToken):
    """用户登录视图"""

    def post(self, request, *args, **kwargs):
        # 校验用户操作验证码成功以后的ticket临时票据
        try:
            api = TencentCloudAPI()
            result = api.captcha(
                request.data.get("ticket"),
                request.data.get("randstr"),
                request._request.META.get("REMOTE_ADDR"),
            )
            List = request._request.META.get("REMOTE_ADDR")
            print(List)
            if result:
                # 验证通过
                print("验证通过")
                # 登录实现代码，调用父类实现的登录视图方法
                return super().post(request, *args, **kwargs)
            else:
                # 如果返回值不是True，则表示验证失败
                raise TencentCloudSDKException
        except TencentCloudSDKException as err:
            return Response({"errmsg": "验证码校验失败！"}, status=status.HTTP_400_BAD_REQUEST)


class MobileAPIView(APIView):
    def get(self, request, mobile):
        """
        校验手机号是否已注册
        :param request:
        :param mobile: 手机号
        :return:
        """
        try:
            User.objects.get(mobile=mobile)
            return Response({"errmsg": "当前手机号已注册"}, status=status.HTTP_400_BAD_REQUEST)
        except User.DoesNotExist:
            # 如果查不到该手机号的注册记录，则证明手机号可以注册使用
            return Response({"errmsg": "OK"}, status=status.HTTP_200_OK)


class UserAPIView(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserRegisterModelSerializer


import random
from django_redis import get_redis_connection
from django.conf import settings
# from ronglianyunapi import send_sms
from .tasks import send_sms

class SMSAPIView(APIView):
    def get(self, request, mobile):
        """
        发送短信验证码
        get_redis_connection 是获取Redis数据库的链接方式，
        括号中的是Redis的链接方式，写在settings中的dev中
        """
        redis = get_redis_connection("sms_code")
        # 判断手机短信是否处于发送冷却中[dev中规定写好了60秒才能发一条]
        interval = redis.ttl(f"interval_{mobile}")
        if interval != -2:
            # 当短信处于冷却中提示并返回一个400状态值
            return Response({
                "errmsg": f"短信发送过于频繁，请于{interval}秒后再次点击获取！"
            },
                status=status.HTTP_400_BAD_REQUEST
            )

        # 随机生成一个六位数的验证码，基于random生成
        code = f"{random.randint(0,999999):06d}"
        # 短信验证码的有效时间
        time = settings.RONGLIANYUN.get("sms_expire")
        # 短信验证码获取间隔时间
        sms_interval = settings.RONGLIANYUN.get("sms_interval")
        # 调用第三方sdk发送短信
        # settings.RONGLIANYUN.get("reg_tid"):调用短信模板
        # mobile:用户手机号
        # dates=(code, time // 60)：code是验证码,time是验证码的有效时间
        # send_sms(settings.RONGLIANYUN.get("reg_tid"), mobile, datas=(code, time // 60))
        send_sms.delay(settings.RONGLIANYUN.get("reg_tid"), mobile, datas=(code, time // 60))
        """
        将code记录到Redis中，并且将time作为有效期
        使用Redis提供的管道对象pipeline来优化Redis的写入操作[添加、修改、删除]
        pipeline是将多次对Redis操作打包到一起，一次提交到Redis中，以此减少对Redis读写的操作次数以提高Redis效率
        """
        pipe = redis.pipeline()
        # 开启事物
        pipe.multi()
        # 设置验证码的有效时间在Redis中写如用户手机号，验证码，并设置时效性
        pipe.setex(f"sms_{mobile}", time, code)
        # 设置验证码冷却时间，在Redis中写入用户手机号，并将验证码冷却时间设置为有效时间
        pipe.setex(f"interval_{mobile}", sms_interval, "_")
        # 通过pipe一次性提交给Redis
        pipe.execute()

        return Response({"errmsg":"验证已经发送"}, status=status.HTTP_200_OK)
